/**
 * 功能： 管理全局广播 (common/bus/bus.js中引用)
 * import EventBus from '@/common/bus/event-bus.js'
 * const bus = new EventBus()
 * //注册一个事件(同一类型只能注册一次，即同一函数名称名称，只能注册一次)
 * bus.register(observer, eventName, false, subscriber);
 * //注册一个粘性事件(同一类型只能注册一次，即同一函数名称名称，只能注册一次)
 * bus.register(observer, eventName, true, subscriber);
 * //移除页面所有监听事件
 * bus.unRegister(observer);
 * //发送事件消息
 * bus.post(eventName, msg);
 * //发送粘性事件（消息，同一个类型，只保留最后一个）
 * bus.postSticky(eventName, msg);
 * //销毁所有(谨慎调用)
 * bus.destroy();
 * 
 * 作者： caihan
 * 日期:  2021-05-19
 */
const eventsHolder = {
	observerList: [], //观察对象列表
	stickyEvents: [], //粘性事件(消息)
}

/**
 * 获取消息名
 * @param {Object} eventName 消息名
 */
function getRegisterType(eventType) {
	return eventType ? eventType : "defaultType";
}

export default class EventBus {

	/**
	 * 发送粘性事件（消息，同一个类型，只保留最后一个）
	 * @param {Object} eventType 事件类型
	 * @param {Object} msg 消息
	 */
	postSticky(eventType, msg) {
		const registerType = getRegisterType(eventType);
		const findIndex = eventsHolder.stickyEvents.findIndex(item => item.eventType === registerType);
		if (findIndex >= 0) {
			eventsHolder.stickyEvents[findIndex].msg = msg;
		} else {
			eventsHolder.stickyEvents.push({
				eventType: registerType,
				msg: msg,
			})
		}
		this.post(registerType, msg);
	}

	/**
	 * 发送事件消息
	 * @param {Object} eventType 事件类型
	 * @param {Object} msg 消息
	 */
	post(eventType, msg) {
		const postType = getRegisterType(eventType);
		eventsHolder.observerList.forEach(item => {
			if (postType === item.eventType && item.subscriber && (item.subscriber instanceof Function)) {
				item.subscriber({
					eventType: item.eventType,
					msg: msg
				});
			}
		})
	}


	/**
	 * 注册一个事件(同一类型只能注册一次，即同一函数名称名称，只能注册一次)
	 * @param {Object} observer 需要观察的对象 this
	 * @param {Object} eventType 观察的对象事件类型，可确省,默认为 "defaultType"
	 * @param {Object} sticky 是否是粘性事件，可确省,默认为false
	 * @param {Object} subscriber 订阅回调
	 */
	register(observer, eventType = 'defaultType', sticky = false, subscriber) {
		if (subscriber instanceof Function) {
			const registerType = getRegisterType(eventType);
			if (sticky) {
				//粘性事件,注册的时候看是否有需要接受的消息,有的话直接回调
				let findStickyEventIndex = eventsHolder.stickyEvents.findIndex(item => item.eventType ===
					registerType);
				if (findStickyEventIndex >= 0) {
					let findEvent = eventsHolder.stickyEvents[findStickyEventIndex];
					if (findEvent && subscriber && (subscriber instanceof Function)) {
						subscriber(findEvent);
						eventsHolder.stickyEvents.splice(findStickyEventIndex, 1);
					}
				}
			} else {
				//先找观察对象列表
				let findIndex = eventsHolder.observerList.findIndex(item => item.observer === observer && item
					.eventType === eventType);
				if (findIndex < 0) {
					eventsHolder.observerList.push({
						observer: observer,
						subscriber: subscriber,
						eventType: registerType,
					})
				}
			}
		} else {
			console.error({
				message: 'EventBus listener subscriber mast be a Function',
				callFunc: 'adapter:_register'
			})
			// throw Error();
		}
	}

	/**
	 * 解除注册
	 * @param {Object} observer 需要观察的对象 this
	 */
	unRegister(observer) {
		eventsHolder.observerList = eventsHolder.observerList.filter(item => item.observer !== observer);
	}

	/**
	 * 销毁所有(谨慎调用)
	 */
	destroy() {
		eventsHolder.stickyEvents = []
		eventsHolder.observerList = []
	}
}
